package com.zrx.govern.component.easyexcel.starter.handler;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.zrx.govern.component.easyexcel.starter.entity.FieldDataType;
import com.zrx.govern.component.easyexcel.starter.enums.FieldDataTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;

/**
 * @author zhangxiaowei
 * @desc easyexcel自定义写入拦截器，用于处理自定义format的数据
 */
@Slf4j
public class CustomFormatCellWriteHandler implements CellWriteHandler {

    @Override
    public int order() {
        return 10;
    }

    /**
     * 数字格式 控制数字的格式map
     */
    private Map<Integer,FieldDataType> formatMap;
    /**
     * CellStyle的map,不同index的列CellStyle隔离开
     */
    private Map<Integer,CellStyle> cellStyleMap;

    private CellStyle normalCellStyle;

    public CustomFormatCellWriteHandler(Map<Integer, FieldDataType> numFormatMap) {
        this.formatMap = numFormatMap;
        this.cellStyleMap = new HashMap<>(2);
    }

    @Override
    public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {

    }

    /**
     * withTemplate形式即填充格式(非声明式传入head，此方法的head对象为null)
     * head.getColumnIndex()会报空指针异常
     * @param writeSheetHolder
     * @param writeTableHolder
     * @param cell
     * @param head
     * @param relativeRowIndex
     * @param isHead
     * @return: void
     * @author zhangxiaowei
     **/
    @Override
    public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        if (!isHead){
            if(formatMap.containsKey(cell.getColumnIndex())) {
                if (Objects.isNull(cellStyleMap.get(cell.getColumnIndex()))) {
                    // 获取 Workbook对象
                    Workbook workbook = writeSheetHolder.getSheet().getWorkbook();
                    // 创建一个 CellStyle对象
                    CellStyle cellStyle = workbook.createCellStyle();
                    DataFormat dataFormat = workbook.createDataFormat();
                    FieldDataType fieldDataType = formatMap.get(cell.getColumnIndex());
                    cellStyle.setDataFormat(dataFormat.getFormat(fieldDataType.getFormat()));
                    cellStyle.setAlignment(HorizontalAlignment.LEFT);
                    cellStyleMap.put(cell.getColumnIndex(), cellStyle);
                }
                cell.setCellStyle(cellStyleMap.get(cell.getColumnIndex()));
            }else{
                /*除数字列，所有其他列共用此样式*/
                if (Objects.isNull(normalCellStyle)) {
                    // 获取 Workbook对象
                    Workbook workbook = writeSheetHolder.getSheet().getWorkbook();
                    // 创建一个 CellStyle对象
                    CellStyle cellStyle = workbook.createCellStyle();
                    cellStyle.setAlignment(HorizontalAlignment.LEFT);
                    normalCellStyle = cellStyle;
                }
                cell.setCellStyle(normalCellStyle);
            }
        }
    }

    /**
     * 按照json文件设置的format格式化处理数据
     * @param writeSheetHolder
     * @param writeTableHolder
     * @param cellData
     * @param cell
     * @param head
     * @param relativeRowIndex
     * @param isHead
     */
    @Override
    public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, WriteCellData<?> cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        if(!isHead && formatMap.containsKey(cell.getColumnIndex())) {
            FieldDataType fieldDataType = formatMap.get(cell.getColumnIndex());
            FieldDataTypeEnum fieldDataTypeEnum = fieldDataType.getFieldDataTypeEnum();
            switch (fieldDataTypeEnum) {
                case NUMBER:
                    if (NumberUtil.isNumber(cellData.getStringValue())) {
                        BigDecimal bigDecimal = new BigDecimal(cellData.getStringValue());
                        DecimalFormat df = new DecimalFormat(fieldDataType.getFormat());
                        //指定RoundingMode
                        df.setRoundingMode(RoundingMode.HALF_UP);
                        cellData.setStringValue(df.format(bigDecimal));
                    }
                    break;
                case DATE:
                    Date date = validDate(cellData.getStringValue());
                    if (Objects.nonNull(date)) {
                        cellData.setStringValue(DateUtil.format(date,fieldDataType.getFormat()));
                    }
                default:
                    break;
            }
        }
    }

    /**
     * 判断转换的时间字符串
     * @param date
     * @return
     */
    private static Date validDate(String date) {
        if (StringUtils.isBlank(date)) {
            return null;
        }
        try {
            return DateUtil.parse(date);
        } catch (Exception e) {
            return null;
        }
    }


    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {

    }

}
